package com.jee.ssm.modules.hik.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.setting.dialect.Props;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jee.ssm.common.utils.ImageBase64;
import com.jee.ssm.common.utils.UUIDFactory;
import com.jee.ssm.model.*;
import com.jee.ssm.model.json.Tip;
import com.jee.ssm.modules.handheld.services.HandheldService;
import com.jee.ssm.modules.hikDevice.services.HikDeviceService;
import com.jee.ssm.modules.hikDeviceBerth.services.HikDeviceBerthService;
import com.jee.ssm.modules.order.services.OrderService;
import com.jee.ssm.modules.passData.services.PassDataService;
import com.jee.ssm.modules.posuserBerth.services.PosuserBerthService;
import org.apache.log4j.Logger;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author YanZengBao
 * @Description
 * @date 2020/7/17
 */
@Controller
@RequestMapping("/hik")
public class HikController {

    private Logger logger = Logger.getLogger(HikController.class);
    @Autowired
    private AmqpTemplate amqpTemplate;

    public void logInfo(String content){
        logger.info("海康摄像头:" + content);
    }

    // 海康摄像头传过来的车辆抓拍数据
    @RequestMapping(value = "/record/car")
    @ResponseBody
    public String getHikCarRecord(@RequestBody HashMap<String,Object> map){
        logInfo("收到数据");
        Integer triggerID = (Integer) map.get("TriggerID");
        String deviceID =(String) map.get("DeviceID");
        //解析组装过车数据
        resolvePassData(map);

        //发送提示信息给手持机
        sendPos(deviceID);

        //回复报文内容
        Map map1 = new HashMap();
        map1.put("Status","OK");
        map1.put("TriggerID",triggerID);
        String s1 = JSON.toJSONString(map1);
        //System.out.println(s1);
        return s1;
    }


    /**
     * 描述： 解析组装过车数据
     * 创建时间：2020/7/23  YanZengBao
     * 修改时间：2020/7/23  YanZengBao 加注释
     * 修改时间：
     */
    public void resolvePassData(HashMap<String,Object> map){
        //System.out.println();
        logInfo("解析组装过车数据");
        String format = DateUtil.format(new Date(), "yyyyMMdd");
        //过车记录实体
        PassData passData = new PassData();
        passData.setId(UUIDFactory.getStringId());
        //passData.setPassTime(new Date());

        String deviceID =(String) map.get("DeviceID");
        String License = (String) map.get("License");
        String PicScene1 = (String)map.get("PicScene1");//Base64图片
        //String parkingNum = (String) map.get("parkingNum");//车位不准确 暂时不用
        String PassTime = (String) map.get("PassTime");//PassTime=20210420140159159
        Date newPassTime = DateUtil.parse(PassTime);
        Integer ByCarDirectType = (Integer) map.get("ByCarDirectType");//方向不准确  暂时不用   (1进 2出)
        //        System.out.println("处理后的信息：设备编号：" + deviceID + ",抓拍时间：" + PassTime + "，车牌号：" + License + "，图片数量：" + PicNum + ",车位号：" + parkingNum +
//                ",方向："+ ByCarDirectType);

        //保存停车场信息
        HikDevice hikDevice = hikDeviceService.selectByNumber(deviceID);
        if(hikDevice != null){
            passData.setParkId(hikDevice.getParkId());
            passData.setParkName(hikDevice.getParkName());
        }
        //解析车牌号
        if(License != null && !"".equals(License)){
            //解析车牌颜色
            String plateColor = (String) License.subSequence(0, 1);
            if(plateColor.equals("蓝")){
                passData.setPlateColor("1");
            }else if(plateColor.equals("黄")){
                passData.setPlateColor("2");
            }else if(plateColor.equals("黑")){
                passData.setPlateColor("3");
            }else if(plateColor.equals("白")){
                passData.setPlateColor("4");
            }else if(plateColor.equals("绿")){
                passData.setPlateColor("5");
            }else{
                passData.setPlateColor("0");
            }
            //解析车牌号
            String plateNo = (String)License.subSequence(1,License.length());
            passData.setPlateNo(plateNo);
        }
        passData.setSbCode(deviceID);//设备编号（海康设备编号）
        passData.setFinishStatus(0);//进出场完成状态
        passData.setVehType(1);//小车
        if(ByCarDirectType == 1){
            passData.setDirection(0);//方向：未知 （数据库  0-入 1-出 2-未知）
        }else if(ByCarDirectType == 2){
            passData.setDirection(1);
        }else{
            passData.setDirection(2);
        }
        passData.setPassTime(newPassTime);

        //windows 环境下的路径（已测试）
        File file = new File("E:\\passingRecord\\images\\" + format + "\\");
        //如果文件夹不存在则创建
        if (!file.exists() && !file.isDirectory()) {
            boolean isMk = file.mkdirs();
            logInfo("目录创建状态：" + isMk);
        }

        String bigImage = "PicScene1" + System.currentTimeMillis() + ".jpg";
        String bigImageUrl = "E:\\passingRecord\\images\\" + format + "\\" + bigImage;//图片保存的绝对路径
        String saveBig = "/images/" + format + "/" + bigImage; // 抓拍图片 即将保存到数据库的路径
        //base64编码字符串转换为图片
        ImageBase64.generateImage(PicScene1, bigImageUrl);
        passData.setPassPicPath(saveBig);
        try {
            //数据保存到本地
            passDataService.insert(passData);
            //数据同步到服务器
            insertServerPassData(passData);

            //判断进出方向生成订单（2是出场）
            if(ByCarDirectType == 2){
                logInfo("出场,保存订单");
                //枪机生成订单
                insertOrder(passData);
            }
        }catch (Exception e){
            e.printStackTrace();
            logInfo("保存枪机传过来的过车数据异常！");
        }
    }

    /**
     * 描述： 枪机抓拍准备保存订单并同步到服务器
     * 创建时间：2021/4/25  YanZengBao
     * 修改时间：2021/4/25  YanZengBao 加注释
     * 修改时间：
     */
    private void insertOrder(PassData passData) throws Exception{
        logInfo("枪机抓拍准备保存订单并同步到服务器");
        //根据停车场  和车牌号查询最近的一条未完成的记录
        Map map = new HashMap();
        map.put("parkId",passData.getParkId());
        map.put("plateNo",passData.getPlateNo());
        List<PassData> passDataList = passDataService.queryByPlateNo(map);
        if(passDataList != null && !passDataList.isEmpty()){
            Date inTime = passDataList.get(0).getPassTime();
            passData.setInPassTime(inTime);
            String inPassRecordId = passDataList.get(0).getId();//进场ID
            passData.setInUniqueNo(inPassRecordId);

            //本地存储订单
            double money = 0.00;
            //判断收费规则是否正常
            Tip tip = orderService.normalBill(passData);
            if(tip.getSuccess()){
                logInfo("收费规则通过验证");
                if (tip.getData() != null){
                    money = (Double) tip.getData();
                    passData.setShouldPay(money);
                }else {
                    passData.setShouldPay(0.0);
                }
                //修改原出场记录数据
                passData.setFinishStatus(1);
                passDataService.updateById(passData);
                //修改原进场记录数据
                passDataList.get(0).setFinishStatus(1);
                passDataService.updateById(passDataList.get(0));

                if(passData.getShouldPay() != 0.0){

                    logInfo("计费不是0元");
                    //生成订单
                    long min = (passData.getPassTime().getTime() - passData.getInPassTime().getTime()) / 60000;
                    int time2 = (int)min;
                    //订单对象
                    Order order = new Order(UUIDFactory.getStringId(),UUIDFactory.getStringId(),passData.getParkId(),passData.getParkName(),time2,passData.getInPassTime(),passData.getPassTime(),
                            null, passData.getPlateNo(),passData.getPlateColor(),0,money,passData.getVehType().toString(),null);
                    orderService.insert(order);
                    //同步订单到平台服务器
                    insertServerOrder(order);
                }else{
                    logInfo("记录计费0元订单不保存");
                }
            }
        }else{
            logInfo("未找到进场记录");
        }
    }

    /**
     * @Description 同步订单到平台服务器
     * @author yanzengbao
     * @date 2019/8/15 下午3:34
     */
    private void insertServerOrder(Order order){
        try {
            Props props = new Props("config/project.properties");
            String url = props.getProperty("server.url");
            String method = props.getProperty("tc.insertOrder");
            String jsonOrder = JSONObject.toJSONString(order);
            HttpRequest.post(url + method).form("jsonOrder",jsonOrder).execute().body();
        }catch (Exception e){
            e.printStackTrace();
            logInfo("服务器未链接！");
        }
    }


    /**
     * 描述： 记录同步服务器
     * 创建时间：2020/7/23  YanZengBao
     * 修改时间：2020/7/23  YanZengBao 加注释
     * 修改时间：
     */
    private void insertServerPassData(PassData passData){
        try {
            //Map map = new HashMap();
            Props props = new Props("config/project.properties");
            String serverUrl = props.getProperty("server.url");
            String method = props.getProperty("tc.insertPassData");
            String jsonPassData = JSONObject.toJSONString(passData);
            //map.put("jsonPassData",jsonPassData);

            if(passData.getPassPicPath() != null && !"".equals(passData.getPassPicPath())){
                String qz_url = "E:/passingRecord";
                String realPath = qz_url + passData.getPassPicPath();
                logInfo("读取图片实际存储路径,上传过车记录和图片");
                File file = new File(realPath);
                HttpRequest.post(serverUrl + method).form("jsonPassData",jsonPassData).form("passImg",file).execute().body();
            }else{
                //没有读取到过车记录中的图片路径
                logInfo("没有读取到过车记录中的图片路径，只上传过车记录");
                HttpRequest.post(serverUrl + method).form("jsonPassData",jsonPassData).execute().body();
            }
        }catch (Exception e){
            e.printStackTrace();
            logInfo("服务器未链接!");
        }
    }

    /**
     * 描述： 收到抓拍数据发送信息给手持机
     * 创建时间：2020/7/20  YanZengBao
     * 修改时间：2020/7/20  YanZengBao 加注释
     * 修改时间：
     */
    public void sendPos(String hikNumber){
        logInfo("发送信息给手持机");

        List<PosuserBerth> posuserBerths = new ArrayList<>();
        List<String> userIdList = new ArrayList<>();

        //根据设备编号查询设备车位关联表数据
        Map map = new HashMap();
        map.put("hikNumber",hikNumber);
        List<HikDeviceBerth> hikDeviceBerthList = hikDeviceBerthService.selectByParam(map);
        if(hikDeviceBerthList != null && !hikDeviceBerthList.isEmpty()){
            //System.out.println("设备车位关联表数据不是空！");
            for (HikDeviceBerth hdb:hikDeviceBerthList) {
                PosuserBerth posuserBerth = posuserBerthService.selectByBerthId(hdb.getBerthId());
                if(posuserBerth != null){
                    posuserBerths.add(posuserBerth);
                }
            }
        }
        //根据手持机用户车位关联关系查询用户IDs
        if(posuserBerths != null && !posuserBerths.isEmpty()){
            //System.out.println("用户车位关联数据不是i空！");
            for (PosuserBerth pb: posuserBerths) {
                userIdList.add(pb.getUserId());
            }
        }
        //根据用户IDs查询手持机
        if(userIdList != null && !userIdList.isEmpty()){
            //System.out.println("用户IDs 不是空！");
            //（用户去重）
            userIdList = userIdList.stream().distinct().collect(Collectors.toList());
            for (String userId:userIdList) {
                Handheld handheld = handheldService.selectByUserId(userId);

                if(handheld != null){
                    logInfo("手持机登陆用户ID" + handheld.getUserId() + "，手持机编号：" + handheld.getPosNumber());
                    //给手持机发送提示信息
                    logInfo("发送");
                    Map map1 = new HashMap();
                    map1.put("type","1");
                    String msg = JSON.toJSONString(map1);
                    amqpTemplate.convertAndSend(handheld.getPosNumber(),msg);
                }
            }
        }
    }

    @Resource
    private HikDeviceService hikDeviceService;
    @Resource
    private HikDeviceBerthService hikDeviceBerthService;
    @Resource
    private PosuserBerthService posuserBerthService;
    @Resource
    private HandheldService handheldService;
    @Resource
    private PassDataService passDataService;
    @Resource
    private OrderService orderService;


}
